package com.ap.core.business.message.response.translators.impl;

import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;

import com.ap.core.business.message.domain.translators.BindingMetaData;
import com.ap.core.business.message.response.translators.ResponseMetaData;
import com.ap.core.business.message.response.translators.ResponseTranslator;
import com.ap.core.business.message.response.translators.listener.ResponseListener;
import com.ap.core.common.types.MessageStatus;
import com.ap.core.common.types.PaymentResponseStatusType;
import com.ap.core.cxf.jaxb.acknowledgement.MessageStatusEnum;
import com.ap.core.cxf.jaxb.common.ResponseWithIntentType;
import com.ap.core.cxf.jaxb.common.YNType;
import com.ap.core.cxf.jaxb.managepayment.AckStatusType;
import com.ap.core.cxf.jaxb.managepayment.EndpointType;
import com.ap.core.cxf.jaxb.managepayment.EndpointsType;
import com.ap.core.cxf.jaxb.managepayment.NotifyRecipientInfoType;
import com.ap.core.cxf.jaxb.managepayment.PaymentStatusType;
import com.ap.core.cxf.jaxb.managepayment.QuickpayDelType;
import com.ap.core.cxf.jaxb.paymentdetails.TxnStatusType;
import com.ap.core.dao.DistributorDao;
import com.ap.core.dao.DistributorEndPointUrlDao;
import com.ap.core.dao.MerchantDao;
import com.ap.core.dao.ZappConsumerUserDao;
import com.ap.core.domain.Distributor;
import com.ap.core.domain.DistributorEndPointUrl;
import com.ap.core.domain.Merchant;
import com.ap.core.domain.OrderPayment;
import com.ap.core.domain.ZappConsumerUser;
import com.ap.core.message.managepayment.info.ConfirmPaymentRequestMessageInfo;
import com.ap.core.message.managepayment.info.ConfirmPaymentResponseMessageInfo;

/**
 * User: Rohit.Dixit
 * implementation class for {@link ResponseTranslator} to populate {@link ResponseWithIntentType}  in response object
 */
public class ConfirmPaymentResponseTranslator implements ResponseTranslator<ConfirmPaymentRequestMessageInfo, ConfirmPaymentResponseMessageInfo> {

    private final static EnumSet<MessageStatus> processedInputMessages = EnumSet.of(MessageStatus.AUTHORISED, MessageStatus.DECLINED);

	 private DistributorDao distributorDao;
	 private MerchantDao merchantDao;
	 private DistributorEndPointUrlDao distributorEndPointUrlDao;
     private ZappConsumerUserDao zappConsumerUserDao;


    /**
     * {@inheritDoc}
     */
    @Override
    public void populateResponse(ConfirmPaymentRequestMessageInfo request, ConfirmPaymentResponseMessageInfo response, BindingMetaData bindingMetaData, ResponseMetaData responseMetaData, ResponseListener responseListener) {

        final MessageStatus originalMessageStatus = bindingMetaData.getOriginalReadOnlyOrderPayment() == null ? null : bindingMetaData.getOriginalReadOnlyOrderPayment().getStatusCode();
        boolean isDuplicate = false;
        if(null != originalMessageStatus && processedInputMessages.contains(originalMessageStatus)){
            isDuplicate = true;
        }
    	 final OrderPayment originalOrderPayment = responseMetaData.getOriginalReadOnlyOrderPayment();
    	
         final NotifyRecipientInfoType notifyRecipientInfo = new NotifyRecipientInfoType();

         final EndpointsType endpoints = new EndpointsType();

         final Merchant merchant = merchantDao.findById(originalOrderPayment.getMerchantId());
         
         final Distributor distributor = distributorDao.findById(originalOrderPayment.getDistributorId());
         
         notifyRecipientInfo.setMerchantId(merchant.getMerchantIdentification());

         notifyRecipientInfo.setDistributorId(distributor.getDistributorIdentification());
         
         notifyRecipientInfo.setRTPId(originalOrderPayment.getRtpId());

        if(isDuplicate){
            notifyRecipientInfo.setNotifyDistributor(YNType.N);
        }else{
            notifyRecipientInfo.setNotifyDistributor(YNType.Y);
        }

         List<DistributorEndPointUrl> urlList = distributorEndPointUrlDao.findByDistributorId(originalOrderPayment.getDistributorId());
        
         List<EndpointType> endpointList = new ArrayList<EndpointType>();
         
         for(DistributorEndPointUrl url : urlList){
        	 EndpointType endpoint = new EndpointType();
        	 endpoint.setSiteName(url.getSiteName());
        	 endpoint.setTargetURI(url.getEndpointUrl());
        	 endpointList.add(endpoint);
         }
         
         endpoints.getEndpoint().addAll(endpointList);
         
         response.setEndpoints(endpoints);
         
         response.setNotifyRecipientInfo(notifyRecipientInfo);
         
         AckStatusType ackStatusType = new AckStatusType();
         ackStatusType.setMessageStatus(MessageStatusEnum.RECD);
         response.setAckStatus(ackStatusType);

        if(com.ap.core.cxf.jaxb.rtp.TransactionCheckOutType.QKPACHK.equals(originalOrderPayment.getTransactionCheckoutType())  && com.ap.core.cxf.jaxb.common.DeliveryType.DIGDEL.equals(originalOrderPayment.getDeliveryType())){
            ZappConsumerUser zappConsumerUser = zappConsumerUserDao.getZappConsumerUserByFiIdentificationAndZappCustomerId(request.getConsumerAcct().getFIId(), originalOrderPayment.getZappConsumerId());
            QuickpayDelType quickPayDel = new QuickpayDelType();
            quickPayDel.setQkPayDelEmail(zappConsumerUser.getZappEmailId());
            response.setQuickpayDel(quickPayDel);
        }
        
        // Set PaymentStatus in response based on ConfirmPaymentRequest TxnStatus
        PaymentStatusType paymentStatusType = new PaymentStatusType();
        
        paymentStatusType.setTxnStatus(request.getPaymtDetails().getPaymentStatusInfo().getTxnStatus());
        
        if(request.getPaymtDetails().getPaymentStatusInfo().getTxnStatus() == TxnStatusType.DECLINED){
        	paymentStatusType.setTxnStatusDesc(PaymentResponseStatusType.getMessageType(request.getPaymtDetails().getPaymentStatusInfo().getTxnStatusCode()));
        }
        
        response.setPaymentStatus(paymentStatusType);

        responseListener.onMessageResponse(response);

    }
    
    public void setDistributorDao(DistributorDao distributorDao) {
        this.distributorDao = distributorDao;
    }

    public void setMerchantDao(MerchantDao merchantDao) {
        this.merchantDao = merchantDao;
    }

	public void setDistributorEndPointUrlDao(DistributorEndPointUrlDao distributorEndPointUrlDao) {
		this.distributorEndPointUrlDao = distributorEndPointUrlDao;
	}

    public void setZappConsumerUserDao(ZappConsumerUserDao zappConsumerUserDao) {
        this.zappConsumerUserDao = zappConsumerUserDao;
    }
}
